Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Rendered • View rawDownload


vendor/lxmfy/README.md dev (af76f09d) Text, 10.57 KB

LXMFy

Easily create LXMF bots for the Reticulum Network with this extensible framework.


Feature

┌──────────────┬───────────────────────────────────────────────────────────────────────────────────┐
│ Category │ Key Capabilities │
├──────────────┼───────────────────────────────────────────────────────────────────────────────────┤
Core │ Interactive CLI, Command Prefixes, Cron-style Task Scheduler, Middleware & Event… │
Connectivity │ Direct Delivery & Propagation Fallback, Auto-Peering, RNS Link Support, Opportun… │
Security │ Spam Protection, Role-based Permissions, Identity Pinning, Message Signing/Verif… │
NLP │ Local NLP Intent Classification (Offline/Private), Type-hinted Argument Parsing │
Extensions │ Python Cogs, External Script Cogs (Bash, Go, C, etc.), Linux Sandboxing (Landloc… │
Storage │ Extensible Backends (JSON, SQLite, In-Memory), Message Persistence (Crash Recove… │
Reliability │ Extensive Stability & Mathematical Stress Testing, Chaos Engineering, Resource L… │
UX │ Help on First Message, Auto-generated Help Menus, Customizable Bot Icons, Attach… │
└──────────────┴───────────────────────────────────────────────────────────────────────────────────┘

Installation

Requirements: Python 3.11+, RNS 1.3.8+, LXMF 1.0.1+, cbor2 5.4.0+ (installed automatically with LXMFy).

There are many ways to install LXMFy, you pick:

From PyPI

T282828
T8b949e# pip
pip install lxmfy

T8b949e# pipx
pipx install lxmfy


Development Installation

For development, clone the repository and install with poetry:

T282828
git clone https://git.quad4.io/LXMFy/LXMFy.git
Tffa657cd LXMFy


T282828
poetry install

Usage

T282828
lxmfy

Create bots:

T282828
lxmfy create

Docker

Building Manually

To build the Docker image, navigate to the root of the project and run:

T282828
docker build -t lxmfy-test .

Once built, you can run the Docker image:

T282828
docker run -d Tffea00\
--name lxmfy-test-bot Tffea00\
-v Tff7b72$(Tffa657pwdTff7b72)/config:/bot/config Tffea00\
-v Tff7b72$(Tffa657pwdTff7b72)/.reticulum:/root/.reticulum Tffea00\
--restart unless-stopped Tffea00\
lxmfy-test


Auto-Interface support (network host):

T282828
docker run -d Tffea00\
--name lxmfy-test-bot Tffea00\
--network host Tffea00\
-v Tff7b72$(Tffa657pwdTff7b72)/config:/bot/config Tffea00\
-v Tff7b72$(Tffa657pwdTff7b72)/.reticulum:/root/.reticulum Tffea00\
--restart unless-stopped Tffea00\
lxmfy-test


Building Wheels with docker/Dockerfile.Build

The T383838docker/Dockerfile.Build is used to build the T383838lxmfy Python package into a wheel file within a Docker image.

T282828
docker build -f docker/Dockerfile.Build -t lxmfy-wheel-builder .

This will create an image named T383838lxmfy-wheel-builder. To extract the built wheel file from the image, you can run a container from this image and copy the T383838dist directory:

T282828
docker run --rm -v Ta5d6ff"Tff7b72$(Tffa657pwdTff7b72)Ta5d6ff/dist_output:/outputTa5d6ff" lxmfy-wheel-builder


This command will create a T383838dist_output directory in your current working directory and copy the built wheel file into it.

Example

T282828
Tff7b72from T7ee787lxmfy Tff7b72import Te6edf3LXMFBotTb4b4b4, Te6edf3load_cogs_from_directory

Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffLXMFy Test BotTa5d6ff"Tb4b4b4, T8b949e# Name of the bot that appears on the network.
Te6edf3announceTff7b72=T79c0ff5400Tb4b4b4, T8b949e# Announce every hour, set to 0 to disable.
Te6edf3announce_enabledTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Set to False to disable all announces (both initial and periodic)
Te6edf3announce_immediatelyTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Set to False to disable initial announce
Te6edf3adminsTff7b72=Tb4b4b4[Ta5d6ff"Ta5d6ffyour_lxmf_hash_hereTa5d6ff"Tb4b4b4]Tb4b4b4, T8b949e# List of admin hashes.
Te6edf3hot_reloadingTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Enable hot reloading.
Te6edf3command_prefixTff7b72=Ta5d6ff"Ta5d6ff/Ta5d6ff"Tb4b4b4, T8b949e# Set to None to process all messages as commands.
Te6edf3cogs_dirTff7b72=Ta5d6ff"Ta5d6ffcogsTa5d6ff"Tb4b4b4, T8b949e# Specify cogs directory name.
Te6edf3rate_limitTff7b72=T79c0ff5Tb4b4b4, T8b949e# 5 messages per minute
Te6edf3cooldownTff7b72=T79c0ff5Tb4b4b4, T8b949e# 5 seconds cooldown
Te6edf3max_warningsTff7b72=T79c0ff3Tb4b4b4, T8b949e# 3 warnings before ban
Te6edf3warning_timeoutTff7b72=T79c0ff300Tb4b4b4, T8b949e# Warnings reset after 5 minutes
Te6edf3signature_verification_enabledTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Enable cryptographic signature verification
Te6edf3require_message_signaturesTff7b72=Tff7b72FalseTb4b4b4, T8b949e# Allow unsigned messages but log them
Te6edf3propagation_fallback_enabledTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Enable propagation fallback after direct delivery fails
Te6edf3propagation_nodeTff7b72=Ta5d6ff"Ta5d6ffyour_propagation_node_hash_hereTa5d6ff"Tb4b4b4, T8b949e# Manual propagation node (optional)
Te6edf3autopeer_propagationTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Auto-discover propagation nodes (optional)
Te6edf3autopeer_maxdepthTff7b72=T79c0ff4Tb4b4b4, T8b949e# Max hops for auto-peering (default: 4)
Te6edf3enable_propagation_nodeTff7b72=Tff7b72FalseTb4b4b4, T8b949e# Run as propagation node (default: False)
Te6edf3message_storage_limit_mbTff7b72=T79c0ff500Tb4b4b4, T8b949e# Storage limit in MB for propagation node (default: 500)
Te6edf3direct_delivery_retriesTff7b72=T79c0ff3Tb4b4b4, T8b949e# Number of direct delivery attempts before falling back to propagation
Te6edf3landlock_enabledTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Linux Landlock LSM sandbox for the bot process (default)
Te6edf3external_cogs_sandbox_enabledTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Sandbox external script cogs on Linux
Te6edf3external_cogs_sandbox_typeTff7b72=Ta5d6ff"Ta5d6ffautoTa5d6ff"Tb4b4b4, T8b949e# auto, landlock, bwrap, firejail, or none
Tb4b4b4)

T8b949e# Dynamically load all cogs
Te6edf3load_cogs_from_directoryTb4b4b4(Te6edf3botTb4b4b4)

Tf0883e@botTff7b72.Td2a8ffcommandTb4b4b4(Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffpingTa5d6ff"Tb4b4b4, Te6edf3descriptionTff7b72=Ta5d6ff"Ta5d6ffTest if bot is responsiveTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffpingTb4b4b4(Te6edf3ctxTb4b4b4)Tb4b4b4:
Te6edf3ctxTff7b72.Td2a8ffreplyTb4b4b4(Ta5d6ff"Ta5d6ffPong!Ta5d6ff"Tb4b4b4)

T8b949e# Admin Only Command
Tf0883e@botTff7b72.Td2a8ffcommandTb4b4b4(Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffechoTa5d6ff"Tb4b4b4, Te6edf3descriptionTff7b72=Ta5d6ff"Ta5d6ffEcho a messageTa5d6ff"Tb4b4b4, Te6edf3admin_onlyTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72def Td2a8ffechoTb4b4b4(Te6edf3ctxTb4b4b4, Te6edf3messageTb4b4b4: Tffa657strTb4b4b4)Tb4b4b4:
Te6edf3ctxTff7b72.Td2a8ffreplyTb4b4b4(Te6edf3messageTb4b4b4)

Te6edf3botTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4)


RRC (Reticulum Relay Chat)

Bots can join RRC hubs as ordinary clients over RNS Links with CBOR envelopes:

T282828
Tff7b72from T7ee787lxmfy Tff7b72import Te6edf3LXMFBotTb4b4b4, Te6edf3RRCMessage

Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffRoomBotTa5d6ff"Tb4b4b4,
Te6edf3rrc_enabledTff7b72=Tff7b72TrueTb4b4b4,
Te6edf3rrc_hubsTff7b72=Tb4b4b4[Ta5d6ff"Ta5d6ffyour_rrc_hub_destination_hashTa5d6ff"Tb4b4b4]Tb4b4b4,
Te6edf3rrc_roomsTff7b72=Tb4b4b4[Ta5d6ff"Ta5d6fflobbyTa5d6ff"Tb4b4b4]Tb4b4b4,
Te6edf3rrc_nickTff7b72=Ta5d6ff"Ta5d6ffRoomBotTa5d6ff"Tb4b4b4,
Tb4b4b4)

Tf0883e@botTff7b72.Td2a8ffon_rrc
Tff7b72def Td2a8ffon_rrcTb4b4b4(Te6edf3eventTb4b4b4, Te6edf3clientTb4b4b4, Te6edf3payloadTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3event Tff7b72== Ta5d6ff"Ta5d6ffmsgTa5d6ff" Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3payloadTb4b4b4, Te6edf3RRCMessageTb4b4b4) Tff7b72and Te6edf3payloadTff7b72.Td2a8ffmentionTb4b4b4:
Te6edf3clientTff7b72.Td2a8ffsend_messageTb4b4b4(Te6edf3payloadTff7b72.Td2a8ffroomTb4b4b4, Ta5d6fffTa5d6ff"Ta5d6ffHeard you, Tffd700{Te6edf3payloadTff7b72.Td2a8ffnickTffd700}Ta5d6ff"Tb4b4b4)

Te6edf3botTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4)


Or connect at runtime with T383838bot.connect_rrc(hub_hash, rooms=["lobby"]).

Hub sessions persist across restarts by default (T383838rrc_persist_sessions=True). Outgoing LXMF messages are also persisted by default (T383838message_persistence_enabled=True) so a crash mid-queue does not drop them. The outbound queue is bounded (T383838message_queue_size, default 50) and drops the oldest message when full.

Propagation Node Configuration

LXMFy supports three modes for propagation node usage:

1. Manual Configuration

Set a specific propagation node by hash:

T282828
Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffMyBotTa5d6ff"Tb4b4b4,
Te6edf3propagation_fallback_enabledTff7b72=Tff7b72TrueTb4b4b4,
Te6edf3propagation_nodeTff7b72=Ta5d6ff"Ta5d6ffyour_propagation_node_hash_hereTa5d6ff"Tb4b4b4, T8b949e# Manual node configuration
Te6edf3direct_delivery_retriesTff7b72=T79c0ff3Tb4b4b4,
Tb4b4b4)


2. Automatic Discovery (Auto-Peering)

Let the bot automatically discover and use propagation nodes from network announces:

T282828
Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffMyBotTa5d6ff"Tb4b4b4,
Te6edf3propagation_fallback_enabledTff7b72=Tff7b72TrueTb4b4b4,
Te6edf3autopeer_propagationTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Enable automatic discovery
Te6edf3autopeer_maxdepthTff7b72=T79c0ff4Tb4b4b4, T8b949e# Maximum hop distance for auto-peering (default: 4)
Tb4b4b4)


The bot will listen for propagation node announces and automatically peer with suitable nodes within the configured hop depth.

3. Run as Propagation Node

Your bot can act as a propagation node itself to store and forward messages:

T282828
Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffMyPropagationBotTa5d6ff"Tb4b4b4,
Te6edf3enable_propagation_nodeTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Enable propagation node mode
Te6edf3message_storage_limit_mbTff7b72=T79c0ff500Tb4b4b4, T8b949e# Limit storage to 500 MB (default)
Tb4b4b4)


When running as a propagation node, the bot will store messages for offline users and forward them when the recipients come online. The T383838message_storage_limit_mb prevents the bot from consuming unlimited disk space. Set to 0 for unlimited storage (not recommended).

Querying Propagation Status

You can check the current propagation configuration and discovered nodes:

T282828
Te6edf3status Tff7b72= Te6edf3botTff7b72.Td2a8ffget_propagation_node_statusTb4b4b4(Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCurrent outbound node: Tffd700{Te6edf3statusTb4b4b4[Ta5d6ff'Ta5d6ffcurrent_outbound_nodeTa5d6ff'Tb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffDiscovered peers: Tffd700{Te6edf3statusTb4b4b4[Ta5d6ff'Ta5d6ffdiscovered_peersTa5d6ff'Tb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4)


Dynamically Setting Propagation Node

You can change the propagation node at runtime:

T282828
Te6edf3botTff7b72.Td2a8ffset_propagation_nodeTb4b4b4(Ta5d6ff"Ta5d6ffnew_propagation_node_hashTa5d6ff"Tb4b4b4)


Managing Storage Limits

When running as a propagation node, you can query and adjust storage limits:

T282828
T8b949e# Get current storage statistics
Te6edf3stats Tff7b72= Te6edf3botTff7b72.Td2a8ffget_propagation_storage_statsTb4b4b4(Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffStorage used: Tffd700{Te6edf3statsTb4b4b4[Ta5d6ff'Ta5d6ffstorage_size_mbTa5d6ff'Tb4b4b4]Tffd700:Ta5d6ff.2fTffd700}Ta5d6ff MBTa5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffStorage limit: Tffd700{Te6edf3statsTb4b4b4[Ta5d6ff'Ta5d6ffstorage_limit_mbTa5d6ff'Tb4b4b4]Tffd700}Ta5d6ff MBTa5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffUtilization: Tffd700{Te6edf3statsTb4b4b4[Ta5d6ff'Ta5d6ffutilization_percentTa5d6ff'Tb4b4b4]Tffd700:Ta5d6ff.1fTffd700}Ta5d6ff%Ta5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffMessages stored: Tffd700{Te6edf3statsTb4b4b4[Ta5d6ff'Ta5d6ffmessage_countTa5d6ff'Tb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4)

T8b949e# Change storage limit at runtime
Te6edf3botTff7b72.Td2a8ffset_message_storage_limitTb4b4b4(Te6edf3megabytesTff7b72=T79c0ff1000Tb4b4b4) T8b949e# Set to 1 GB


Important Notes

• Without configuring propagation (manual, auto-peer, or running as a node), messages requiring propagation will fail
• You can combine modes: e.g., set a manual node AND enable auto-peering as backup
• When running as a propagation node, your bot can still send and receive messages normally
• Auto-peering respects the T383838autopeer_maxdepth setting to avoid connecting to distant nodes

Security & Sandboxing

On Linux kernels with Landlock support (5.13+), LXMFy can restrict filesystem access for the bot process and for external script cogs.

Bot process sandbox

When T383838landlock_enabled=True (default), the bot applies a Landlock LSM sandbox after startup. System paths are read-only; bot storage, config, cogs, Reticulum config, and temp directories remain writable.

T282828
Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffSecureBotTa5d6ff"Tb4b4b4,
Te6edf3landlock_enabledTff7b72=Tff7b72TrueTb4b4b4,
Tb4b4b4)

Te6edf3status Tff7b72= Te6edf3botTff7b72.Td2a8ffget_landlock_statusTb4b4b4(Tb4b4b4)
Tffa657printTb4b4b4(Te6edf3statusTb4b4b4)


Environment overrides:

• T383838LXMFY_LANDLOCK=0 — disable Landlock
• T383838LXMFY_LANDLOCK=1 — force an attempt on Linux
• unset — follow T383838landlock_enabled and kernel auto-detection

External script cog sandbox

Executable cogs in T383838cogs/ can run in a restricted environment when T383838external_cogs_sandbox_enabled=True (default). Set T383838external_cogs_sandbox_type to:

• T383838auto (default) — prefer Landlock, then T383838bwrap, then T383838firejail
• T383838landlock — Landlock-only via T383838preexec_fn
• T383838bwrap — bubblewrap read-only bind sandbox
• T383838firejail — firejail private profile with no network
• T383838none — no subprocess sandbox

See the docs for full configuration details.

Development

• Python 3.11+
Poetry

T282828
poetry install
poetry run lxmfy run Tffa657echo


Common Makefile targets:

T282828
make lint T8b949e# ruff check
make typecheck T8b949e# pyright lxmfy
make Tffa657test T8b949e# pytest
make ci T8b949e# lint, typecheck, security check, test, build


Contributing

For now send ideas and issues to LXMF: T3838387cc8d66b4f6a0e0e49d34af7f6077b5a

License

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────